/*

	Gauss Gun
	By Foss

*/

if ( SERVER ) then

	AddCSLuaFile( "shared.lua" )
	
end

if ( CLIENT ) then

	SWEP.PrintName			= "Gauss Gun"
	SWEP.Author				= "Foss"
	SWEP.Instructions		= "Fire a normal-powered gauss blast with primary fire\nCharge up a more powerful gauss blast with secondary fire"
	SWEP.Category			= "SMOD"
	
	SWEP.Slot				= 2
	SWEP.SlotPos			= 5
	
	SWEP.DrawAmmo			= false
	SWEP.DrawCrosshair		= true
	SWEP.ViewModelFOV		= 70
	
	SWEP.AnimPrefix			= "smg"
	
end

SWEP.ViewModel				= "models/weapons/v_smg1.mdl"
SWEP.WorldModel				= "models/weapons/w_smg1.mdl"

SWEP.Spawnable				= true
SWEP.AdminSpawnable			= true

SWEP.Primary.ClipSize		= 100
SWEP.Primary.DefaultClip	= 200
SWEP.Primary.Automatic		= true
SWEP.Primary.Ammo			= "smg1"

SWEP.Secondary.ClipSize		= 0
SWEP.Secondary.DefaultClip	= 0
SWEP.Secondary.Automatic 	= false
SWEP.Secondary.Ammo			= "none"

SWEP.StartCharge			= 0
SWEP.MaxCharge				= 10
SWEP.ChargeAmount			= 0
SWEP.NextCharge				= CurTime()
SWEP.Damage					= 15
SWEP.MaxDamage				= 100

SWEP.Charging				= false
SWEP.FullCharge				= false
SWEP.Playing				= false
SWEP.CanFire				= true

SWEP.ChargeSound			= nil


function SWEP:Initialize()

	if ( SERVER ) then
	
		self:SetWeaponHoldType( "smg" )
	
	end
	
end
	
function SWEP:FireGauss()

	local owner = self.Owner
	
	local startpos = owner:GetShootPos()
	local aim = owner:GetAimVector()
	local up = owner:GetUp()
	local right = owner:GetRight()
	
	local endpos = startpos + ( aim * 4096 )
	
	local trace = {}
	trace.start = startpos
	trace.endpos = endpos
	trace.filter = owner
	trace.mask = MASK_SHOT
	
	local tr = util.TraceLine( trace )
	
	local min, max = Vector( -5, -5, -5 ), Vector( 5, 5, 5 )
	local tscale = GetConVarNumber( "phys_timescale" )
	local force = self.Damage * 2 * tscale
	
	if ( ValidEntity( tr.Entity ) ) then
	
		owner:TraceHullAttack( tr.StartPos, tr.HitPos, min, max, self.Damage, DMG_SHOCK, force, true )
	
	end
	
	self:DrawBeam( tr.StartPos, tr.HitPos, 1.6 )
	
	local fx = EffectData()
	fx:SetOrigin( tr.HitPos )
	fx:SetStart( tr.HitPos )
	fx:SetNormal( tr.HitNormal )
	util.Effect( "ImpactGauss", fx )

	self:TakePrimaryAmmo( 1 )
	self.Weapon:SetNextPrimaryFire( CurTime() + 0.2 )

end


function SWEP:FireCharged()

	local owner = self.Owner

	self.Charging = false
	self.FullCharge = false

	local startpos = owner:GetShootPos()
	local aim = owner:GetAimVector()
	local endpos = startpos + ( aim * 4096 )
	
	local trace = {}
	trace.start = startpos
	trace.endpos = endpos
	trace.filter = owner
	trace.mask = MASK_SHOT
	
	local tr = util.TraceLine( trace )
	
	local min, max = Vector( -5, -5, -5 ), Vector( 5, 5, 5 )
	local tscale = GetConVarNumber( "phys_timescale" )

	//Find how much damage to do
	local charge = math.Clamp( ( CurTime() - self.ChargeAmount ) / self.MaxCharge, 0, 1 )

	//Determine the damage amount
	local damage = self.Damage + ( ( self.MaxDamage - self.Damage ) * charge )
	
	local force = damage * 2 * tscale

	if ( ValidEntity( tr.Entity ) ) then
	
		if ( SERVER ) then
		
			owner:TraceHullAttack( tr.StartPos, tr.HitPos, min, max, damage, DMG_SHOCK, force, true )
		
		end
	
	end

	local fx = EffectData()
	fx:SetOrigin( tr.HitPos )
	fx:SetStart( tr.HitPos )
	fx:SetNormal( tr.HitNormal )
	util.Effect( "ImpactGauss", fx )

	local punch = Angle( math.Rand( -4, -8 ), math.Rand( -0.25, 0.25 ), 0 )
	owner:ViewPunch( punch )

	self:DrawBeam( tr.StartPos, tr.HitPos, 9.6 )
	
	local ang = owner:GetAngles()
	local dir = Vector( ang:Forward(), ang:Right(), 0 ):Normalize()
	
	self.Owner:EmitSound( "weapons/gauss/fire1.wav" )
	
	util.Decal( "RedGlowFade", tr.HitPos + tr.HitNormal, tr.HitPos - tr.HitNormal )
	
	self.Weapon:SetNextPrimaryFire( CurTime() + 0.2 )
	self.Weapon:SetNextSecondaryFire( CurTime() + 0.5 )

end

function SWEP:DrawBeam( startpos, endpos, width )

	local attachment = self.Owner:GetViewModel():GetAttachment( "1" )
	local mpos = attachment.Pos
	local muzzlepos = self.Owner:GetShootPos() + self.Owner:GetForward() * 75 + self.Owner:GetRight() * 15 + self.Owner:GetUp() * -12
	muzzlepos = muzzlepos + ( self.Owner:GetRight() * Vector( 60, 60, 0 ) )

	if ( SERVER ) then
	
		local startent = ents.Create( "info_target" )
		startent:SetPos( muzzlepos )
		startent:SetName( "gaussStart" )
		
		local endent = ents.Create( "info_target" )
		endent:SetPos( endpos )
		endent:SetName( "gaussEnd" )
		
		local beam = ents.Create( "env_beam" )
		beam:SetAngles( Angle( 260, 0, 0 ) )
		beam:SetKeyValue( "LightningStart", "gaussStart" )
		beam:SetKeyValue( "LightningEnd", "gaussEnd" )
		beam:SetKeyValue( "rendercolor", "255 " .. 185 + math.random( -16, 16 ) .. " 40" )
		beam:SetKeyValue( "renderamt", 255 )
		beam:SetKeyValue( "texture", "sprites/laserbeam.vmt" )
		beam:SetKeyValue( "damage", 0 )
		beam:SetKeyValue( "spawnflags", 1 )
		beam:SetKeyValue( "framestart", 0 )
		beam:SetKeyValue( "framerate", 0 )
		beam:SetKeyValue( "NoiseAmplitude", 0 )
		beam:SetKeyValue( "TextureScroll", 0 )
		beam:SetKeyValue( "life", 0.1 )
		beam:SetKeyValue( "TouchType", 0 )
		beam:SetKeyValue( "Radius", 256 )
		beam:SetKeyValue( "StrikeTime", 1 )
		beam:SetKeyValue( "BoltWidth", width )
		
		local bolts = ents.Create( "env_beam" )
		bolts:SetKeyValue( "LightningStart", "gaussStart" )
		bolts:SetKeyValue( "LightningEnd", "gaussEnd" )
		bolts:SetKeyValue( "rendercolor", "255 255 " .. 150 + math.random( 0, 64 ) )
		bolts:SetKeyValue( "renderamt", math.random( 64, 255 ) )
		bolts:SetKeyValue( "texture", "sprites/laserbeam.vmt" )
		bolts:SetKeyValue( "damage", 0 )
		bolts:SetKeyValue( "spawnflags", 1 )
		bolts:SetKeyValue( "framestart", 0 )
		bolts:SetKeyValue( "framerate", 0 )
		bolts:SetKeyValue( "NoiseAmplitude", 1.6 )
		bolts:SetKeyValue( "TextureScroll", 0 )
		bolts:SetKeyValue( "life", 0.1 )
		bolts:SetKeyValue( "TouchType", 0 )
		bolts:SetKeyValue( "Radius", 256 )
		bolts:SetKeyValue( "StrikeTime", 1 )
		bolts:SetKeyValue( "BoltWidth", 3 )
		
		beam:Fire( "turnon", "", "" )
		bolts:Fire( "turnon", "", "" )
		
		startent:Spawn()
		endent:Spawn()
		beam:Spawn()
		bolts:Spawn()
		
 		beam:Fire( "kill", "", 0.1 )
		bolts:Fire( "kill", "", 0.1 )
		startent:Fire( "kill", "", 0.1 )
		endent:Fire( "kill", "", 0.1 )
	
	end

end

function SWEP:PrimaryAttack()

	if ( self.Weapon:Clip1() <= 0 ) then
	
		return
	
	end

	self.Owner:EmitSound( "weapons/gauss/fire1.wav" )
	self:FireGauss()

end

function SWEP:SecondaryAttack()

	if ( self.Weapon:Clip1() <= 0 ) then
	
		if ( self.ChargeSound != nil ) then
		
			self.ChargeSound:FadeOut( 0.1 )
		
		end
	
		return
	
	end
	
	if ( !self.Charging ) then
	
		
		//Start looping sound
		if ( self.ChargeSound == nil ) then
		
			self.ChargeSound = CreateSound( self.Owner, "weapons/gauss/chargeloop.wav" )
			self.ChargeSound:Play()
			self.ChargeSound:ChangePitch( 250 )
			self.Playing = true
		
		end
		
		if ( self.ChargeSound != nil and !self.Playing ) then
		
			self.ChargeSound:Play()
			self.ChargeSound:ChangePitch( 250 )
			self.Playing = true
		
		end
		
		self.Charging = true
		self.FullCharge = false
		self.CanFire = true
		self.ChargeAmount = 0
		
	end

end

function SWEP:Think()

	//Make sure we can draw power
	if ( self.Weapon:Clip1() <= 0 and self.ChargeAmount != 0 and self.CanFire ) then
	
		self:FireCharged()
		self.ChargeAmount = 0
		self.CanFire = false
		return
	
	end

	if ( self.Owner:KeyPressed( IN_ATTACK2 ) and self.ChargeAmount == 0 ) then
	
		return
	
	end
	


	if ( self.Owner:KeyDown( IN_ATTACK2 ) ) then
		
		if ( self.FullCharge ) then
		
			return
		
		end

		local owner = self.Owner

		//Check our charge time
		if ( self.ChargeAmount < self.MaxCharge ) then
		
			if ( self.NextCharge > CurTime() ) then
			
				return
			
			end
			
			self.ChargeAmount = self.ChargeAmount + 1
			self:TakePrimaryAmmo( 1 )
			
			//Notify the player they're at maximum charge
			if ( self.ChargeAmount == 10 ) then
			
				self.FullCharge = true
			
			end
			
			self.NextCharge = CurTime() + 0.2
		
			return
		
		end
	
	
	end

	if ( self.Owner:KeyReleased( IN_ATTACK2 ) ) then
	
		self:FireCharged()
		
		if ( self.ChargeSound != nil ) then
		
			self.ChargeSound:FadeOut( 0.1 )
		
		end
		
		self.Weapon:SetNextSecondaryFire( CurTime() + 0.5 )
		self.Playing = false
		self.FullCharge = false
	
	end

end

function SWEP:Holster()

	if ( self.ChargeSound != nil ) then
	
		self.ChargeSound:FadeOut( 0.1 )
	
	end
	
	return true
	
end

